package com.example.myproject.client;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class Location{
	int x;
	int y;
	
	Location(int newX, int newY){
		x = newX;
		y = newY;
	}
	
	boolean isValid(){
		if (x>=0 && x<=100 && y>=0 && y<=50){
			if (!(x>=40 && x<=50 && y>=40 && y<=50)){
				return true;
			}
		}
		return false;
	}
}


public class ConfigGenerator {
	List <Module> modList = new ArrayList<Module>();
	List <Module> newConfig = new ArrayList<Module>();
	List <Location> intersections= new ArrayList<Location>();
	List <String> types = new ArrayList<String>();
	String dir = "Right";
	List <Location> used = new ArrayList<Location>();
	List <Location> spot = new ArrayList<Location>();
	Location cur = new Location(0,0);
	int distance = 0;
	
	Module tempMod;
	
	ConfigGenerator (List <Module> modules){
		modList = modules;
		
		spot.add(new Location(1,0));
		spot.add(new Location(1,1));
		spot.add(new Location(1,-1));
		spot.add(new Location(2,0));
		spot.add(new Location(2,1));
		spot.add(new Location(2,-1));
		spot.add(new Location(3,0));
		spot.add(new Location(3,1));
		spot.add(new Location(3,-1));
		spot.add(new Location(4,0));
		spot.add(new Location(4,1));
		spot.add(new Location(4,-1));
		spot.add(new Location(5,0));
		
	}
	
	int getDist(){
		return distance;
	}
	
	Location direct(String direction, Location before){
		Location after = new Location(0,0);
		if (direction.compareTo("Left") !=0){
			return before;
		}
		else if (direction.compareTo("Right")!=0){
			after.x = before.x*-1;
			after.y = before.y;
			return after;
		}
		else if (direction.compareTo("Up")!=0){
			after.x = before.y;
			after.y = before.x;
			return after;
		}
		else{
			after.x = before.y*-1;
			after.y = before.x;
			return after;
		}
	}
	Module FindAndUse(String type){
		Module returnMod = new Module();
		for (Module m : modList){
			if (m.getType().equals(type)){
				returnMod = m;
				modList.remove(m);
				return returnMod;
			}
		}
		return returnMod;
	}
	
	void findValidMod(Location loc){
		types.clear();
		Location checkLoc = new Location(0,0);
		if (dir == "Left"){
			checkLoc = new Location(loc.x+1, loc.y);
		}
		else if (dir == "Right"){
			checkLoc = new Location(loc.x-1, loc.y);
		}
		else if (dir == "Up"){
			checkLoc = new Location(loc.x, loc.y-1);
		}
		else if (dir == "Down"){
			checkLoc = new Location(loc.x, loc.y+1);
		}
		
		Module prevMod = new Module();
		
		for(Module t : modList){
			if (t.getX()==checkLoc.x && t.getY() == checkLoc.y){
				prevMod = t;
				break;
			}
		}
		
		if (prevMod.getType() == "Plain"){
			types.add("Plain");
		}
		if (prevMod.getType() == "Airlock"){
			types.add("Airlock");
			types.add("Control");
			types.add("Power");
			types.add("Canteen");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Sanitation");
			types.add("Food & Water");
		}
		else if (prevMod.getType() == "Dormitory"){
			types.add("Control");
			types.add("Power");
			types.add("Canteen");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Sanitation");
			types.add("Food & Water");
			types.add("Dormitory");
		}
		else if(prevMod.getType() == "Sanitation"){
			types.add("Airlock");
			types.add("Control");
			types.add("Power");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Sanitation");
			types.add("Dormitory");
		}
		else if (prevMod.getType() == "Food & Water"){
			types.add("Airlock");
			types.add("Control");
			types.add("Power");
			types.add("Canteen");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Food & Water");
			types.add("Dormitory");
		}
		else if (prevMod.getType() == "Canteen"){
			types.add("Airlock");
			types.add("Control");
			types.add("Power");
			types.add("Canteen");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Food & Water");
			types.add("Dormitory");
		}
		else {
			types.add("Airlock");
			types.add("Control");
			types.add("Power");
			types.add("Canteen");
			types.add("Gym & Relaxation");
			types.add("Medical");
			types.add("Sanitation");
			types.add("Food & Water");
			types.add("Dormitory");
		}
		
		
	}
	
	List<Module> Generate(){
		int x = 0;
		int y = 0;
		int spotCounter = 0;
		
		for (Module i: modList){
			x += i.getX();
			y += i.getY();
		}
		
		Module tempMod = FindAndUse("Plain");
		
		tempMod.setX(x);
		tempMod.setY(y);
		
		Location start = new Location(x,y);
		intersections.add(start);
		
		newConfig.add(tempMod);
		
		cur = intersections.get(0);
		
		while(!modList.isEmpty()){
			Location newLoc = new Location((cur.x + spot.get(spotCounter).x) ,(cur.y + spot.get(spotCounter).y));
			newLoc = direct(dir, newLoc);
			
			if (newLoc.isValid() && spotCounter < spot.size() && !used.contains(newLoc)){
				findValidMod(newLoc);
				int size = types.size();
				int rando = new Random().nextInt(size);
				String newType = types.get(rando);
				Module addMod = FindAndUse(newType);
				
				distance += 2*(Math.sqrt((Math.abs(addMod.getX()-newLoc.x))^2 + (Math.abs(addMod.getY()-newLoc.y))^2));
				
				addMod.setX(newLoc.x);
				addMod.setY(newLoc.y);
				newConfig.add(addMod);
				used.add(newLoc);
				spotCounter++;
				if (spotCounter == spot.size()){
					intersections.add(newLoc);
				}
			}
			else{
				
				spotCounter = 0;
				
				if (!used.contains(new Location(cur.x+1,cur.y))){
					dir = "Right";
				}
				else if (!used.contains(new Location(cur.x,cur.y-1))){
					dir = "Down";
				}
				else if (!used.contains(new Location(cur.x-1,cur.y))){
					dir = "Left";
				}
				else if (!used.contains(new Location(cur.x,cur.y+1))){
					dir = "Up";
				}
				else{
					intersections.remove(0);
					cur = intersections.get(0);
					dir = "Right";
				}
		
			}
		}
		return newConfig;
	}
	
	
}
 